package com.dingreading.cloud.admin.service.impl;

import com.dingreading.cloud.admin.entity.WhPurchaseGoods;
import com.dingreading.cloud.admin.entity.table.WhPurchaseGoodsTableDef;
import com.dingreading.cloud.admin.mapper.WhPurchaseGoodsMapper;
import com.dingreading.cloud.admin.service.WhPurchaseGoodsService;
import com.dingreading.cloud.common.util.EnumType;
import com.dingreading.cloud.common.util.PageDto;
import com.dingreading.cloud.common.util.PageUtil;
import com.google.common.collect.Lists;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryCondition;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.update.UpdateChain;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 服务层实现。
 *
 * @author Administrator
 * @since 2023-11-22
 */
@Service
public class WhPurchaseGoodsServiceImpl extends BaseServiceImpl<WhPurchaseGoodsMapper, WhPurchaseGoods, WhPurchaseGoodsTableDef> implements WhPurchaseGoodsService {

    @Override
    protected WhPurchaseGoodsTableDef getTable() {
        return WhPurchaseGoodsTableDef.whPurchaseGoods;
    }

    @Resource
    WhPurchaseGoodsMapper purchaseGoodsMapper;

    @Override
    public PageDto<WhPurchaseGoods> pageListRealNum(PageUtil pageUtil, String keyword, Integer status, Integer type) {
        //设置其他参数
        Map<String, Object> otherParams = new HashMap<>();
        otherParams.put("status", status);
        otherParams.put("keyword", keyword);
        otherParams.put("type", type);
        otherParams.put("statusList", Lists.newArrayList(EnumType.Purchase.CANCEL.getType(), EnumType.Purchase.SAVE.getType()));

        Page<WhPurchaseGoods> page = getMapper().xmlPaginate("pageListRealNumXml", Page.of(pageUtil.getPage(), pageUtil.getRows()), otherParams);

        long totalRow = page.getTotalRow();
        List<WhPurchaseGoods> list = page.getRecords();

        // 结果
        PageDto<WhPurchaseGoods> dto = new PageDto<>();
        dto.setList(list);
        dto.setTotal(totalRow);
        return dto;
    }

    @Override
    public List<WhPurchaseGoods> getByCode(String purchaseCode) {
        return purchaseGoodsMapper.getByCode(null, purchaseCode);
    }

    @Override
    public List<WhPurchaseGoods> getBeanByCode(String purchaseCode) {
        return getMapper().selectListByCondition(table.purchaseCode.eq(purchaseCode));
    }

    @Override
    public List<WhPurchaseGoods> getByCodes(List<String> purchaseCodes) {
        QueryCondition condition = QueryCondition.createEmpty();
        condition.and(table.purchaseCode.in(purchaseCodes));

        QueryWrapper wrapper = QueryWrapper.create()
                .where(condition)
                .orderBy(table.id.asc());

        return getMapper().selectListByQuery(wrapper);
    }

    @Override
    public WhPurchaseGoods getById(Long id) {
        List<WhPurchaseGoods> list = purchaseGoodsMapper.getByCode(id, null);
        if (CollectionUtils.isNotEmpty(list))
            return list.get(0);
        return null;
    }

    @Override
    public int dropByCodeAndNotIds(String purchaseCode, List<Long> ids) {
        QueryCondition condition = QueryCondition.createEmpty();
        condition.and(table.purchaseCode.eq(purchaseCode));
        if (CollectionUtils.isNotEmpty(ids))
            condition.and(table.id.notIn(ids));
        return getMapper().deleteByCondition(condition);
    }

    @Override
    public int dropData(String purchaseCode) {
        QueryCondition condition = QueryCondition.createEmpty();
        condition.and(table.purchaseCode.eq(purchaseCode));
        return getMapper().deleteByCondition(condition);
    }

    @Override
    public boolean cancel(String purchaseCode) {
        QueryCondition condition = QueryCondition.createEmpty();
        condition.and(table.purchaseCode.eq(purchaseCode));
        condition.and(table.status.in(Lists.newArrayList(EnumType.Purchase.SAVE.getType(), EnumType.Purchase.STEP_1.getType())));
        return UpdateChain.of(WhPurchaseGoods.class)
                .set(table.status, EnumType.Purchase.CANCEL.getType())
                .set(table.statusName, EnumType.Purchase.CANCEL.getName())
                .where(condition)
                .update();
    }

    @Override
    public boolean updateWaitIn(Long id) {
        QueryCondition condition = QueryCondition.createEmpty();
        condition.and(table.id.eq(id));
        condition.and(table.status.eq(EnumType.Purchase.STEP_2.getType()));
        return UpdateChain.of(WhPurchaseGoods.class)
                .set(table.status, EnumType.Purchase.STEP_1.getType())
                .set(table.statusName, EnumType.Purchase.STEP_1.getName())
                .where(condition)
                .update();
    }

    @Override
    public boolean updateEntering(Long id) {
        QueryCondition condition = QueryCondition.createEmpty();
        condition.and(table.id.eq(id));
        condition.and(table.status.eq(EnumType.Purchase.STEP_1.getType()));
        return UpdateChain.of(WhPurchaseGoods.class)
                .set(table.status, EnumType.Purchase.STEP_2.getType())
                .set(table.statusName, EnumType.Purchase.STEP_2.getName())
                .where(condition).update();
    }

    @Override
    public boolean setOk(String purchaseCode, Date time) {
        QueryCondition condition = QueryCondition.createEmpty();
        condition.and(table.purchaseCode.eq(purchaseCode));
        condition.and(table.status.eq(EnumType.Purchase.STEP_2.getType()));
        return UpdateChain.of(WhPurchaseGoods.class)
                .set(table.status, EnumType.Purchase.OK.getType())
                .set(table.statusName, EnumType.Purchase.OK.getName())
                .set(table.okTime, time)
                .where(condition).update();
    }

    @Override
    public long getBySupplierIdAndGoodsTypeId(Long supplierId, Long goodsTypeId) {
        QueryCondition condition = QueryCondition.createEmpty();
        condition.and(table.supplierId.eq(supplierId))
                .and(table.goodsTypeId.eq(goodsTypeId));
        return getMapper().selectCountByCondition(condition);
    }

    @Override
    public boolean notRealSetOk(String purchaseCode, Date time) {
        QueryCondition condition = QueryCondition.createEmpty();
        condition.and(table.purchaseCode.eq(purchaseCode));
        return UpdateChain.of(WhPurchaseGoods.class)
                .set(table.status, EnumType.Purchase.OK.getType())
                .set(table.statusName, EnumType.Purchase.OK.getName())
                .set(table.okTime, time)
                .where(condition).update();
    }

    @Override
    public boolean havesGoodsId(Long goodsId) {
        QueryCondition condition = QueryCondition.createEmpty();
        condition.and(table.goodsId.eq(goodsId));

        return exists(condition);
    }

    @Override
    public boolean havesGoodsTypeId(Long goodsTypeId) {
        QueryCondition condition = QueryCondition.createEmpty();
        condition.and(table.goodsTypeId.eq(goodsTypeId));
        return exists(condition);
    }

    @Override
    public Map<Long, Double> getLastByGoodsTypeIds(List<Long> goodsTypeIds) {
        List<WhPurchaseGoods> list = purchaseGoodsMapper.getLastByGoodsTypeIds(goodsTypeIds);
        Map<Long, Double> unitPriceMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(list))
            unitPriceMap = list.stream().collect(Collectors.toMap(WhPurchaseGoods::getGoodsTypeId, WhPurchaseGoods::getUnitPrice));
        return unitPriceMap;
    }

    @Override
    public List<WhPurchaseGoods> listByGoodsTypeIdIn(List<Long> goodsTypeIds) {
        QueryCondition condition = table.goodsTypeId.in(goodsTypeIds)
                .and(table.status.eq(1));
        return getMapper().selectListByCondition(condition);
    }

}
